package com.icode.service.impl.user;

import com.icode.core.dto.user.*;
import com.icode.core.model.house.UploadImage;
import com.icode.core.model.user.*;
import com.icode.core.shared.ImageUtils;
import com.icode.core.shared.SecurityUtil;
import com.icode.dao.HouseDao;
import com.icode.dao.UserDao;
import com.icode.service.user.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.Random;

/**
 * Created with IntelliJ IDEA.
 * User: sunk
 * Date: 14-12-26
 * Time: 上午11:46
 * To change this template use File | Settings | File Templates.
 */
@Transactional
@Service("userService")
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private HouseDao houseDao;

    @Autowired
    private PasswordEncoder passwordEncoder;


    @Override
    @Transactional
    public byte[] showImageByGuid(String imageGuid) {
        UploadImage image = userDao.findByGuid(UploadImage.class, imageGuid);
        return image.getContents();
    }

    @Override
    @Transactional
    public void saveOrUpdate(UserDTO registerDTO) {
        Customer customer = userDao.findCustomerByUsername(registerDTO.getUsername());
        if (customer == null) {
            String password = registerDTO.getRePassword();
            String encode = passwordEncoder.encode(password);
            registerDTO.setPassword(encode);
            customer = registerDTO.toRegister();
            UserInfo userInfo = new UserInfo(customer);
            customer.initUserInfo(userInfo);
            userDao.saveOrUpdate(customer);
        }
    }

    @Override
    @Transactional
    public boolean login(LoginDTO loginDTO) {
        Customer customer = userDao.findUserForLogin(loginDTO);
        return customer == null ? false : true;
    }

    @Override
    @Transactional
    public Customer findByPhoneNum(String phoneNum) {
        return userDao.findByPhoneNum(phoneNum);
    }


    @Override
    @Transactional
    public void saveOrUpdateUsersInfo(UsersInfoDTO usersInfoDTO, UserInfo userInfo) {
        MultipartFile image = usersInfoDTO.getUsersInfoImage();
        Province province = null;
        City city = null;
        District district = null;
        if (!"noselect".equals(usersInfoDTO.getProvince())) {
            province = userDao.findProvinceById(usersInfoDTO.getProvince());
        }
        if (!"noselect".equals(usersInfoDTO.getCity())) {
            city = userDao.findCityByCityId(usersInfoDTO.getCity());
        }
        if (!"noselect".equals(usersInfoDTO.getDistrict())) {
            district = userDao.findDistrictByDistrictID(usersInfoDTO.getDistrict());
        }
        UserInfo usersInfo = usersInfoDTO.toUsersInfo(userInfo, province, city, district);
        if (image.getSize() > 0) {
            if (userInfo.usersInfoImage() != null) {
                userDao.deleteObject(userInfo.usersInfoImage());
            }
            UploadImage document = ImageUtils.MultipartFileToUploadImage(image);
            usersInfo.initUsersInfoImage(document);
        }
        userDao.saveOrUpdateUsersInfo(usersInfo);
    }

    @Override
    @Transactional
    public UsersInfoDTO initUserInfo(UserInfo userInfo) {
        UsersInfoDTO usersInfoDTO = UsersInfoDTO.toDTO(userInfo);
        if (userInfo.province() != null) {
            List<Province> provinces = userDao.findProvince();
            usersInfoDTO.initProvinces(ProvinceDTO.toDTOs(provinces));
        }
        if (userInfo.city() != null) {
            List<City> cities = userDao.findCityById(String.valueOf(userInfo.province().id()));
            usersInfoDTO.initCities(CityDTO.toDTOs(cities));
        }
        if (userInfo.district() != null) {
            List<District> districts = userDao.findDistrictById(String.valueOf(userInfo.city().id()));
            usersInfoDTO.initDistricts(DistrictDTO.toDTOs(districts));
        }
        return usersInfoDTO;
    }

    @Override
    public List<UserInfo> findUsersInfoByUsername(String username) {
        return userDao.findUsersInfoByUsername(username);
    }


    @Override
    @Transactional
    public List<Province> findProvince() {
        return userDao.findProvince();
    }

    @Override
    @Transactional
    public List<City> findCityById(String provinceId) {
        return userDao.findCityById(provinceId);
    }

    @Override
    @Transactional
    public List<District> findDistrictById(String cityId) {
        return userDao.findDistrictById(cityId);
    }

    @Override
    @Transactional
    public String verify(HttpSession session) {
        Random r = new Random();
        int number = r.nextInt(9000) + 1000;
        session.setAttribute("verify", String.valueOf(number));
        return String.valueOf(number);
    }

    @Override
    @Transactional
    public UsersInfoDTO initUserInfoDTO(User currentUser) {
        UsersInfoDTO usersInfoDTO = new UsersInfoDTO();
        UserInfo userInfo = userDao.findUsersInfoByPhoneNum(currentUser.getUsername());
        if (userInfo == null) {
            usersInfoDTO.setPhoneNum(currentUser.getUsername());
        } else {
            usersInfoDTO = initUserInfo(userInfo);
        }
        usersInfoDTO.setProvinces(ProvinceDTO.toDTOs(findProvince()));
        return usersInfoDTO;
    }

    @Override
    @Transactional
    public UserInfo findUserInfoByUsername(String username) {
        return userDao.findUsersInfoByPhoneNum(username);
    }

    @Override
    @Transactional
    public User findUserByUserName(String username) {
        return userDao.findByPhoneNum(username);
    }

    @Override
    @Transactional
    public UserInfo findUserInfoByUser(User user) {
        return userDao.findUserInfoByUser(user);
    }

    @Override
    @Transactional
    public UserInfo findUserInfoByUsername(String username, String userInfoGuid) {
        return userDao.findUserInfoByUsername(username, userInfoGuid);
    }

    @Override
    @Transactional
    public UsersInfoDTO getUserInfoDTO(String userInfoGuid) {
        UserInfo userInfo = userDao.findByGuid(UserInfo.class, userInfoGuid);
        return UsersInfoDTO.toDTO(userInfo);
    }

    @Override
    @Transactional
    public void updataPassWord(PasswordHandelDTO passwordHandelDTO) {
        User user = SecurityUtil.currentUser();
        String password = passwordEncoder.encode(passwordHandelDTO.getNewPassword());
        if (user == null) {
            String userName = passwordHandelDTO.getUserName();
            if (userDao.userNameIsExist(userName)) {
                user = userDao.findByUserName(userName);
            } else {
                return;
            }
        }
        user.updataPassword(password);
        userDao.saveOrUpdate(user);
    }

    @Override
    @Transactional
    public List<UsersInfoDTO> findAllUserInfo(String currentPage) {
        List<UserInfo> userInfos = userDao.findAllUserInfo(currentPage);
        List<UsersInfoDTO> usersInfoDTOs = UsersInfoDTO.toDTOs(userInfos);
        return usersInfoDTOs;
    }

    @Override
    @Transactional
    public Object findTotalPage(Class clazz) {
        return houseDao.findTotalPage(clazz);
    }

    @Override
    public List<UsersInfoDTO> findUserInfoByPhoneNumAndRealName(String phoneNum, String realName) {
        List<UserInfo> userInfos = userDao.findUserInfoByPhoneNumAndRealName(phoneNum, realName);
        if (phoneNum.equals("") && realName.equals("")) {
            return findAllUserInfo("1");
        } else {
            List<UsersInfoDTO> usersInfoDTOs = UsersInfoDTO.toDTOs(userInfos);
            return usersInfoDTOs;
        }
    }

    @Override
    public void changeUserStatus(String phoneNum, String activate) {
        userDao.changeUserStatus(phoneNum, activate);
    }
}
